// Copyright 2025 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef CLOUDAPPENGINE_CAECONNECTIONAGENT_H
#define CLOUDAPPENGINE_CAECONNECTIONAGENT_H

#include <shared_mutex>
#include "CaeSocketAgent.h"
#include "CaeConnectionPool.h"
#include "../cae_dataHandler/CaeAudioPipeDataHandleThread.h"
#include "../cae_dataHandler/CaeVideoPipeDataHandleThread.h"
#include "../cae_dataHandler/CaeVirtualDeviceDataHandlerThread.h"
#include "../cae_dataHandler/CaeScreenshotPipeDataHandleThread.h"
#include "net_trans.h"

class CaeConnectionAgent {
public:
    CaeConnectionAgent();

    virtual ~CaeConnectionAgent();

    void AddConnector(CaeSocket *socket);

    void CloseConnector();

    int SendCustomDataToClient(const std::shared_ptr<uint8_t>& data, int size, uint8_t type);

private:
    bool IsExclusiveMode();

    void InitMtrans(const std::string& clientVersion);
    void StartMtrans();
    void StopMtrans();
    void DeinitMtrans();

    void InitPipeDataHandlers();
    void DeinitPipeDataHandlers();
    void InitScreenshotDataHandlers();
    void DeInitScreenshotPipeDataHandlers();

    void VerifyResultCallback(bool success, bool secondVerify,
                              const std::string& connectionId, const std::string& ClientPlatformType);
    void ActionCallback(const std::string& connectionId, COMMAND_TYPE commandType);
    void StopAction(const std::string& connectionId);
    void PauseAction(const std::string& connectionId);
    void ResumeAction(const std::string& connectionId);
    void ReconnectAction(const std::string& connectionId);
    void DisconnectCallback(const std::string& connectionId);
    void DisconnectTimeoutCallback(const std::string& connectionId);
    void NotouchTimeoutCallback(const std::string& connectionId);
    void TrialTimeoutCallback(const std::string& connectionId);
    void PauseTimeoutCallback(const std::string& connectionId);

    int SendOrientationDataHook(const std::shared_ptr<uint8_t>& pkt, int size);
    int SendVideoDataHook(void *pkt, int size);
    int SendAudioDataHook(void *pkt, int size);
    int SendVirtualDevDataHook(void *pkt, int size);
    void SendScreenshotDataHook(void *pkt, int size);

    void SendVirtualDeviceStartRequest();

    bool ProcessConnectionMode(const std::string& clientIp, const std::shared_ptr<CaeSocketAgent>& socketAgent);
    bool ProcessResource(const std::shared_ptr<CaeSocketAgent>& socketAgent);
    bool ProcessTimer(const std::shared_ptr<CaeSocketAgent>& socketAgent);
    bool ProcessMedia(const std::shared_ptr<CaeSocketAgent>& socketAgent);
    bool ProcessNotifyToClient(const std::shared_ptr<CaeSocketAgent>& socketAgent);

    bool IsMtransValid(const std::shared_ptr<CaeSocketAgent>& socketAgent);
    bool IsMtransEnable(const std::shared_ptr<CaeSocketAgent>& socketAgent);

    int QueryScreenshotClientNum();

private:
    std::shared_ptr<CaeConnectionPool> m_connectionPool;
    std::unique_ptr<NetTrans> m_mtrans = nullptr;
    std::atomic<bool> m_mtransStarted = {false};

    std::mutex m_mutex;
    std::unique_ptr<CaeAudioPipeDataHandleThread> m_audioPipeDataHandleThread = nullptr;
    std::unique_ptr<CaeVideoPipeDataHandleThread> m_videoPipeDataHandleThread = nullptr;
    std::unique_ptr<CaeVirtualDeviceDataHandlerThread> m_virtualDeviceDataHandleThread = nullptr;
    std::unique_ptr<CaeScreenshotPipeDataHandleThread> m_screenshotPipeDataHandleThread = nullptr;
};


#endif //CLOUDAPPENGINE_CAECONNECTIONAGENT_H
